package com.tryon.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tryon.config.TongYiConfig;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 通义千问AI服务
 * @generatedBy AI-CodeGen
 * @lastModified 2025-10-27
 */
@Slf4j
@Service
public class TongYiService {
    
    @Autowired
    private TongYiConfig tongYiConfig;
    
    private final OkHttpClient client;
    private final ObjectMapper objectMapper;
    
    public TongYiService() {
        this.client = new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)   // 连接超时60秒
            .readTimeout(180, TimeUnit.SECONDS)     // 读取超时3分钟（AI处理需要时间）
            .writeTimeout(60, TimeUnit.SECONDS)     // 写入超时60秒
            .build();
        this.objectMapper = new ObjectMapper();
    }
    
    /**
     * 调用通义千问图像编辑模型进行虚拟试衣（多图融合）
     * @param personImageUrl 人物照片URL
     * @param garmentImageUrl 服装照片URL
     * @param garmentType 服装类型（用于生成更精准的提示词）
     * @param garmentName 服装名称/描述（可选）
     * @return 处理后的图片URL
     */
    public String processTryOn(String personImageUrl, String garmentImageUrl, String garmentType, String garmentName) {
        log.info("========== 开始调用通义千问图像编辑API ==========");
        log.info("模型: {}", tongYiConfig.getModel());
        log.info("人物图片: {}", personImageUrl);
        log.info("服装图片: {}", garmentImageUrl);
        log.info("服装类型: {}", garmentType);
        log.info("服装描述: {}", garmentName);
        
        try {
            // 构建请求体 - 使用多模态格式
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", tongYiConfig.getModel());
            
            // 构建 messages 输入
            Map<String, Object> input = new HashMap<>();
            List<Map<String, Object>> messages = new ArrayList<>();
            Map<String, Object> message = new HashMap<>();
            message.put("role", "user");
            
            // 构建 content 数组（多图 + 文本提示）
            List<Map<String, String>> content = new ArrayList<>();
            
            // 添加人物图片（图1）
            Map<String, String> personImage = new HashMap<>();
            personImage.put("image", personImageUrl);
            content.add(personImage);
            
            // 添加服装图片（图2）
            Map<String, String> garmentImage = new HashMap<>();
            garmentImage.put("image", garmentImageUrl);
            content.add(garmentImage);
            
            // 添加详细的文本描述 - 根据服装类型生成精准提示词
            Map<String, String> textPrompt = new HashMap<>();
            String detailedPrompt = buildPrompt(garmentType, garmentName);
            textPrompt.put("text", detailedPrompt);
            content.add(textPrompt);
            
            log.info("💬 提示语: {}", detailedPrompt);
            
            message.put("content", content);
            messages.add(message);
            input.put("messages", messages);
            requestBody.put("input", input);
            
            // 参数配置
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("negative_prompt", "低质量、模糊、变形");
            parameters.put("watermark", false);
            requestBody.put("parameters", parameters);
            
            // 打印请求体（用于调试）
            String requestBodyStr = objectMapper.writeValueAsString(requestBody);
            log.info("📤 请求体: {}", requestBodyStr);
            
            RequestBody body = RequestBody.create(
                requestBodyStr, 
                MediaType.parse("application/json; charset=utf-8")
            );
            
            // 使用图像编辑API端点
            String apiUrl = "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation";
            log.info("📡 API端点: {}", apiUrl);
            
            Request request = new Request.Builder()
                .url(apiUrl)
                .post(body)
                .addHeader("Authorization", "Bearer " + tongYiConfig.getApiKey())
                .addHeader("Content-Type", "application/json")
                .build();
            
            try (Response response = client.newCall(request).execute()) {
                String responseBody = response.body().string();
                
                log.info("📥 响应状态码: {}", response.code());
                log.info("📥 响应体: {}", responseBody);
                
                if (!response.isSuccessful()) {
                    log.error("❌ 通义万相API调用失败");
                    log.error("状态码: {}", response.code());
                    log.error("响应内容: {}", responseBody);
                    
                    // 解析错误信息
                    try {
                        JsonNode errorNode = objectMapper.readTree(responseBody);
                        String errorCode = errorNode.path("code").asText();
                        String errorMessage = errorNode.path("message").asText();
                        log.error("错误码: {}, 错误信息: {}", errorCode, errorMessage);
                        throw new RuntimeException("AI处理失败: " + errorMessage);
                    } catch (Exception e) {
                        throw new RuntimeException("AI处理失败: HTTP " + response.code());
                    }
                }
                
                JsonNode jsonNode = objectMapper.readTree(responseBody);
                
                // qwen-image-edit 是同步返回的
                String resultImageUrl = extractResultUrl(jsonNode);
                
                if (resultImageUrl == null || resultImageUrl.isEmpty()) {
                    log.error("❌ 返回的图片URL为空");
                    throw new RuntimeException("AI返回的图片URL为空");
                }
                
                log.info("✅ 虚拟试衣处理成功");
                log.info("🖼️  结果图片URL: {}", resultImageUrl);
                return resultImageUrl;
            }
            
        } catch (IOException e) {
            log.error("❌ 调用通义万相API异常", e);
            throw new RuntimeException("AI处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 轮询异步任务结果
     */
    private String pollTaskResult(String taskId) throws IOException {
        int maxRetries = 60;
        int retryCount = 0;
        
        while (retryCount < maxRetries) {
            try {
                Thread.sleep(2000); // 等待2秒
                
                Request request = new Request.Builder()
                    .url("https://dashscope.aliyuncs.com/api/v1/tasks/" + taskId)
                    .get()
                    .addHeader("Authorization", "Bearer " + tongYiConfig.getApiKey())
                    .build();
                
                try (Response response = client.newCall(request).execute()) {
                    String responseBody = response.body().string();
                    JsonNode jsonNode = objectMapper.readTree(responseBody);
                    
                    String status = jsonNode.path("output").path("task_status").asText();
                    log.info("⏳ 任务状态: {} ({}/{})", status, retryCount + 1, maxRetries);
                    
                    if ("SUCCEEDED".equals(status)) {
                        log.info("✅ 任务处理成功");
                        return extractResultUrl(jsonNode);
                    } else if ("FAILED".equals(status)) {
                        String message = jsonNode.path("output").path("message").asText("未知错误");
                        log.error("❌ 任务处理失败: {}", message);
                        throw new RuntimeException("任务处理失败: " + message);
                    }
                    
                    retryCount++;
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("等待任务结果被中断");
            }
        }
        
        throw new RuntimeException("任务处理超时");
    }
    
    /**
     * 根据服装类型构建精准的AI提示词
     */
    private String buildPrompt(String garmentType, String garmentName) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("请帮我完成虚拟试衣任务：\n\n");
        prompt.append("图1：人物照片（模特的全身照或半身照）\n");
        
        // 根据服装类型生成具体描述
        String garmentDescription = getGarmentDescription(garmentType);
        prompt.append("图2：").append(garmentDescription);
        if (garmentName != null && !garmentName.isEmpty()) {
            prompt.append("（").append(garmentName).append("）");
        }
        prompt.append("\n\n");
        
        prompt.append("任务要求：\n");
        prompt.append("1. 让图1中的人物穿上图2中的").append(garmentDescription).append("\n");
        
        // 根据服装类型添加特定要求
        prompt.append(getSpecificRequirements(garmentType));
        
        prompt.append("2. 保持人物原有的姿势、表情和身材比例\n");
        prompt.append("3. 保留原始背景环境\n");
        prompt.append("4. 确保服装自然贴合人物身体，褶皱和光影效果真实\n");
        prompt.append("5. 服装的颜色、图案、材质要与原图完全一致\n");
        prompt.append("6. 输出高质量、自然真实的虚拟试衣效果图\n\n");
        prompt.append("风格：专业摄影效果，高清晰度，自然光线，真实感强");
        
        return prompt.toString();
    }
    
    /**
     * 获取服装类型的中文描述
     */
    private String getGarmentDescription(String garmentType) {
        if (garmentType == null || garmentType.isEmpty()) {
            return "服装";
        }
        
        switch (garmentType.toLowerCase()) {
            case "upper":
            case "top":
                return "上衣（T恤/衬衫/卫衣/毛衣等）";
            case "lower":
            case "pants":
                return "裤子/下装（长裤/短裤/裙子等）";
            case "dress":
                return "连衣裙";
            case "coat":
            case "jacket":
                return "外套（夹克/大衣/风衣等）";
            case "hoodie":
                return "卫衣/帽衫";
            case "sweater":
                return "毛衣/针织衫";
            case "shirt":
                return "衬衫";
            case "tshirt":
                return "T恤";
            case "skirt":
                return "裙子";
            case "jeans":
                return "牛仔裤";
            case "suit":
                return "西装";
            case "accessories":
                return "配饰";
            default:
                return "服装";
        }
    }
    
    /**
     * 根据服装类型获取特定要求
     */
    private String getSpecificRequirements(String garmentType) {
        if (garmentType == null || garmentType.isEmpty()) {
            return "";
        }
        
        StringBuilder requirements = new StringBuilder();
        
        switch (garmentType.toLowerCase()) {
            case "upper":
            case "top":
            case "hoodie":
            case "sweater":
            case "shirt":
            case "tshirt":
                requirements.append("   - 注意上衣的领口、袖口、下摆要自然\n");
                requirements.append("   - 保持上衣的版型和剪裁细节\n");
                break;
            case "lower":
            case "pants":
            case "jeans":
                requirements.append("   - 注意裤子的腰部、裤腿要自然垂坠\n");
                requirements.append("   - 保持裤子的长度和版型\n");
                break;
            case "dress":
                requirements.append("   - 注意裙子的腰线、裙摆要自然流畅\n");
                requirements.append("   - 保持连衣裙的整体廓形和长度\n");
                break;
            case "coat":
            case "jacket":
                requirements.append("   - 注意外套的肩部、袖子、下摆要自然\n");
                requirements.append("   - 保持外套的廓形和层次感\n");
                break;
            case "skirt":
                requirements.append("   - 注意裙子的腰部、裙摆要自然\n");
                requirements.append("   - 保持裙子的长度和蓬松度\n");
                break;
            default:
                requirements.append("   - 注意服装的整体协调性\n");
        }
        
        return requirements.toString();
    }
    
    /**
     * 从响应中提取结果图片URL
     */
    private String extractResultUrl(JsonNode jsonNode) {
        // qwen-image-edit 的响应格式
        // {"output":{"choices":[{"message":{"content":[{"image":"url"}]}}]}}
        JsonNode choices = jsonNode.path("output").path("choices");
        if (choices.isArray() && choices.size() > 0) {
            JsonNode messageContent = choices.get(0).path("message").path("content");
            if (messageContent.isArray() && messageContent.size() > 0) {
                String url = messageContent.get(0).path("image").asText();
                if (!url.isEmpty()) {
                    log.info("✅ 提取到图片URL: {}", url);
                    return url;
                }
            }
        }
        
        // 兼容其他格式
        JsonNode results = jsonNode.path("output").path("results");
        if (results.isArray() && results.size() > 0) {
            String url = results.get(0).path("url").asText();
            if (!url.isEmpty()) {
                return url;
            }
        }
        
        String url = jsonNode.path("output").path("image_url").asText();
        if (!url.isEmpty()) {
            return url;
        }
        
        log.error("❌ 无法从响应中提取图片URL");
        log.error("响应JSON: {}", jsonNode.toPrettyString());
        throw new RuntimeException("无法从响应中提取图片URL");
    }
}

